/**
 * 
 */
package com.gragra.nounIdentification.tests;
import static org.junit.Assert.*;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.StringReader;
import java.io.StringWriter;
import java.util.Arrays;
import org.junit.Before;
import org.junit.Test;
import com.gragra.data.Corpus;
import com.gragra.nounIdentification.ConvergenceByIterations;
import com.gragra.nounIdentification.IncreasingMaxWithMin;
import com.gragra.nounIdentification.LinearIncreasingMax;
import com.gragra.nounIdentification.NounIdentifier;
import com.gragra.nounIdentification.TypesPerTokenScorer;
import com.gragra.sampling.sequentialStructure.ExtensionInformationHolder;
import com.gragra.sampling.sequentialStructure.ExtensionLevels;
import com.gragra.sampling.sequentialStructure.WordAndTagHolder;
import com.gragra.sampling.sequentialStructure.WordType;
import com.gragra.sequentiaDataGenerator.BaseGenerator;
import com.gragra.sequentiaDataGenerator.CaseLevelAssigningSegmenter;
import com.gragra.sequentiaDataGenerator.PunctuationSplitOffSegmenter;
/**
 * @author Christoph Teichmann
 * created Mar 28, 2013 8:45:56 PM
 * @version 0.1
 */
public class TestNounIdentifier
{
	private NounIdentifier ni;
	/**
	 *
	 * @throws java.lang.Exception
	 */
	@Before
	public void setUp() throws Exception
	{
		StringReader sr = new StringReader("A|NONE Cat|1 is|0 on|NONE the|0 mat.|NONE\nA|g horse|NONE is|0 on|NONE the|0 grass.|NONE\nA|j mouse|NONE is|0 in|NONE the|0 trap.|NONE");
		BufferedReader br = new BufferedReader(sr);
		BaseGenerator bg = new BaseGenerator(new CaseLevelAssigningSegmenter(new PunctuationSplitOffSegmenter("NONE")));
		Corpus<WordAndTagHolder>  corp = bg.createCorpus(br);
		ni = new NounIdentifier(corp, 3, 0, 0, new TypesPerTokenScorer(),new ConvergenceByIterations(2), new IncreasingMaxWithMin(new LinearIncreasingMax(1, 1), 2, 5));
		ni.identify();
	}
	/**
	 * Test method for {@link com.gragra.nounIdentification.NounIdentifier#calculateNounTypeCoverage()}.
	 */
	@Test
	public final void testCalculateNounTypeCoverage()
	{assertEquals(0.5,ni.calculateWordTypeCoverage(),0.0000001);}
	/**
	 * Test method for {@link com.gragra.nounIdentification.NounIdentifier#numberOfNouns()}.
	 */
	@Test
	public final void testNumberOfNouns()
	{assertEquals(ni.numberOfWords(),5);}
	/**
	 * Test method for {@link com.gragra.nounIdentification.NounIdentifier#numberOfFrames()}.
	 */
	@Test
	public final void testNumberOfFrames()
	{assertEquals(ni.numberOfFrames(),2);}
	/**
	 * Test method for {@link com.gragra.nounIdentification.BaseNounIdentifier#annotateCorpusFrames(com.gragra.data.Corpus)}.
	 * @throws IOException 
	 */
	@Test
	public final void testAnnotateCorpusFrames() throws IOException
	{
		StringReader sr = new StringReader("A|0 rose|1 is|0 on|1 the|0 table.|1\nThe|NONE cat|NONE is|NONE on|0 the|1 mat.|0");
		BufferedReader br = new BufferedReader(sr);
		BaseGenerator bg = new BaseGenerator(new CaseLevelAssigningSegmenter(new PunctuationSplitOffSegmenter("NONE")));
		Corpus<WordAndTagHolder> corp = bg.createCorpus(br);
		ni.annotateCorpusFrames(corp);
		ExtensionInformationHolder eih = corp.getEntry(0).getExtensionInformation();
		assertFalse(eih.getFiniteInformation(0, ExtensionLevels.WordTypeLevel) == WordType.Noun);
		assertTrue(eih.getFiniteInformation(1, ExtensionLevels.WordTypeLevel) == WordType.Noun);
	}
	/**
	 * Test method for {@link com.gragra.nounIdentification.BaseNounIdentifier#evaluate(com.gragra.data.Corpus, boolean)}.
	 * @throws IOException 
	 */
	@Test
	public final void testEvaluate() throws IOException
	{
		StringReader sr = new StringReader("A|0 rose|1|WordTypeLevel|Noun is|0 on|1 the|0 table.|1\nThe|NONE cat|NONE|WordTypeLevel|Noun is|NONE on|0 the|1 mat.|0");
		BufferedReader br = new BufferedReader(sr);
		BaseGenerator bg = new BaseGenerator(new CaseLevelAssigningSegmenter(new PunctuationSplitOffSegmenter("NONE")));
		Corpus<WordAndTagHolder> corp = bg.createCorpus(br);
		double[] result = ni.evaluate(corp, true);
		assertEquals("[0.3333333333333333, 0.5, 0.4]",Arrays.toString(result));
		result = ni.evaluate(corp, false);
		assertEquals("[0.25, 0.5, 0.3333333333333333]",Arrays.toString(result));
	}
	/**
	 * Test method for {@link com.gragra.nounIdentification.BaseNounIdentifier#evaluateOnSelf(boolean)}.
	 */
	@Test
	public final void testEvaluateOnSelf()
	{
		double[] arr = ni.evaluateOnSelf(true);
		assertEquals("[0.0, 1.0, 0.0]",Arrays.toString(arr));
	}
	/**
	 * Test method for {@link com.gragra.nounIdentification.BaseNounIdentifier#writeOutFrames(java.io.BufferedWriter)}.
	 * @throws IOException 
	 */
	@Test
	public final void testWriteOutFrames() throws IOException
	{
		StringWriter sw = new StringWriter();
		BufferedWriter bw = new BufferedWriter(sw);
		ni.writeOutFrames(bw);
		bw.close();
		String s = sw.toString();
		String[] parts = s.split("\n");
		assertTrue("< is _ the >".equals(parts[0].trim()) || "< is _ the >".equals(parts[1].trim()));
		assertTrue("< a _ is >".equals(parts[0].trim()) || "< a _ is >".equals(parts[1].trim()));
	}
	/**
	 * Test method for {@link com.gragra.nounIdentification.BaseNounIdentifier#writeOutWords(java.io.BufferedWriter)}.
	 * @throws IOException 
	 */
	@Test
	public final void testWriteOutWords() throws IOException
	{
		StringWriter sw = new StringWriter();
		BufferedWriter bw = new BufferedWriter(sw);
		ni.writeOutWords(bw);
		bw.close();
		String s = sw.toString();
		String[] parts = s.trim().split("\n");
		assertEquals("cat",parts[0].trim());
		assertEquals("mouse",parts[1].trim());
	}
	/**
	 * Test method for {@link com.gragra.nounIdentification.BaseNounIdentifier#getSg()}.
	 */
	@Test
	public final void testGetSg()
	{
		assertFalse(null == ni.getSg());
		assertEquals(10,ni.getSg().getAllWords().size());
	}
	/**
	 * Test method for {@link com.gragra.nounIdentification.BaseNounIdentifier#annotateCorpusWords(com.gragra.data.Corpus)}.
	 * @throws IOException 
	 */
	@Test
	public final void testAnnotateCorpusWords() throws IOException
	{
		StringReader sr = new StringReader("A|0 rose|1 is|0 on|1 the|0 table.|1\nThe|NONE cat|NONE is|NONE on|0 the|1 mat.|0");
		BufferedReader br = new BufferedReader(sr);
		BaseGenerator bg = new BaseGenerator(new CaseLevelAssigningSegmenter(new PunctuationSplitOffSegmenter("NONE")));
		Corpus<WordAndTagHolder> corp = bg.createCorpus(br);
		ni.annotateCorpusWords(corp);
		ExtensionInformationHolder eih1 = corp.getEntry(0).getExtensionInformation();
		assertTrue("ExtensionInformationHolder [finiteData=[{CaseTypeLevel=>CapsLockCase}, {CaseTypeLevel=>DownCase}, {CaseTypeLevel=>DownCase}, {WordTypeLevel=>Noun, CaseTypeLevel=>DownCase}, {CaseTypeLevel=>DownCase}, {CaseTypeLevel=>DownCase}, {CaseTypeLevel=>DownCase}], infiniteData=[{}, {}, {}, {}, {}, {}, {}]]".equals(eih1.toString()) ||
				"ExtensionInformationHolder [finiteData=[{CaseTypeLevel=>CapsLockCase}, {CaseTypeLevel=>DownCase}, {CaseTypeLevel=>DownCase}, {CaseTypeLevel=>DownCase, WordTypeLevel=>Noun}, {CaseTypeLevel=>DownCase}, {CaseTypeLevel=>DownCase}, {CaseTypeLevel=>DownCase}], infiniteData=[{}, {}, {}, {}, {}, {}, {}]]".equals(eih1.toString()));
	}
}